# -*- coding: utf-8 -*-
"""
@Time ： 2023/9/26 19:03
@Auth ： weiwenman
@File ：testad.py
@IDE ：PyCharm
"""
# 日志文件简单配置
import json
import os

import openpyxl
from bs4 import BeautifulSoup
import requests


'''
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "file": {
            "level": "DEBUG",
            "class": "logging.FileHandler",
            "filename": os.path.join(os.path.dirname(BASE_DIR),"logs/debug.log"),
        },
    },
    "loggers": {
        "django": {
            "handlers": ["file"],
            "level": "DEBUG",
            "propagate": True,
        },
    },
}
'''

# Logging
# 日志文件规范配置
# LOG_DIR = os.path.join(BASE_DIR, 'logs')
# os.makedirs(LOG_DIR, exist_ok=True)
#
# # 日志配置
# LOGGING = {
#     'version': 1,  # 使用的python内置的logging模块，那么python可能会对它进行升级，所以需要写一个版本号，目前就是1版本
#     'disable_existing_loggers': False,  # 是否去掉目前项目中其他地方中以及使用的日志功能，但是将来我们可能会引入第三方的模块，里面可能内置了日志功能，所以尽量不要关闭。
#     'formatters': {  # 日志记录格式
#         'standard': {  # asctime记录时间，filename 表示日志发生的文件名称，funcName模块方法名，lineno行号，levelname等级，message错误信息
#             'format': '[%(asctime)s]->%(filename)s->%(funcName)s->line:%(lineno)d [%(levelname)s]%(message)s'
#         },
#         'simple': {
#             'format': '%[%(asctime)s]->(levelname)s->%(module)s->%(lineno)d->%(message)s'
#         },
#     },
#     'filters': {  # 过滤器：可以对日志进行输出时的过滤用的
#         'require_debug_true': {  # 在debug=True下产生的一些日志信息，要不要记录日志，需要的话就在handlers中加上这个过滤器，不需要就不加
#             '()': 'django.utils.log.RequireDebugTrue',
#         },
#         'require_debug_false': {  # 和上面相反
#             '()': 'django.utils.log.RequireDebugFalse',
#         },
#     },
#     'handlers': {  # 日志处理方式，日志实例,向哪里输出
#         'console': {  # 在控制台输出时的实例
#             'level': 'INFO',  # 日志等级；debug是最低等级，那么只要比它高等级的信息都会被记录
#             'filters': ['require_debug_true'],  # 在debug=True下才会打印在控制台
#             'class': 'logging.StreamHandler',  # 使用的python的logging模块中的StreamHandler来进行输出
#             'formatter': 'simple'
#         },
#         'file': {
#             'level': 'INFO',
#             'class': 'logging.handlers.RotatingFileHandler',
#             # 日志位置,日志文件名,日志保存目录必须手动创建
#             'filename': os.path.join(LOG_DIR, "my_django.log"),  # 注意，你的文件应该有读写权限。
#             # 日志文件的最大值,这里我们设置300M
#             'maxBytes': 300 * 1024 * 1024,  # B
#             # 日志文件的数量,设置最大日志数量为10
#             'backupCount': 10,
#             # 日志格式:详细格式
#             'formatter': 'standard',
#             'encoding': 'utf-8',  # 设置默认编码，否则打印出来汉字乱码
#         },
#     },
#     # 日志对象
#     'loggers': {
#         'django': {  # 和django结合起来使用，将django中之前的日志输出内容的时候，按照我们的日志配置进行输出，
#             'handlers': ['console', 'file'],  # 将来项目上线，把console去掉
#             'propagate': True,
#             # 冒泡：是否将日志信息记录冒泡给其他的日志处理系统，工作中都是True，不然django这个日志系统捕获到日志信息之后，其他模块中可能也有日志记录功能的模块，就获取不到这个日志信息了
#         },
#     }
# }
# class AdReportManager:
#     """
#     通过上报参数获取广告位id，广告模板，广告非空或空广告，广告上报操作系统
#     """
#
#     def __init__(self, report_params):
#         self.report_params = report_params
#
#     def get_report_ad_os(self):
#         """
#         获取广告操作系统
#         :return:Android或iOS
#         """
#         if 'os' in self.report_params:
#             if 'iOS' in self.report_params['os']:
#                 return 'iOS'
#             else:
#                 return 'Android'
#         elif 'sv' in self.report_params:
#             if 'iOS' in self.report_params['sv']:
#                 return 'iOS'
#             else:
#                 return 'Android'
#         else:
#             return None
#
# def count(request):
#     real_report_params = {k: v for k, v in request.GET.items()}
#     adReportManager = AdReportManager(real_report_params)
#     ad_os = adReportManager.get_report_ad_os()
#     all_params_filepath = get_report_excel(ad_os)
#
#     check_result = JsonResponse(all_params_filepath, json_dumps_params={'ensure_ascii': False})
#
# # 根据操作系统读取本地储存的参数表
# def get_report_excel(report_os):
#
#     current_dir = os.path.dirname(os.path.abspath(__file__))
#     if report_os == 'iOS':
#         all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'iOS_Report__Params.xlsx')
#     else:
#         all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'Android_Report_Params.xlsx')
#
#     return all_params_filepath


# 根据操作系统读取本地储存的参数表
# def get_report_excel(report_os):
#     """
#     根据操作系统读取本地储存的参数表
#     :param report_os:上报操作系统
#     :return:all_params_filepath
#     """
#     current_dir = os.path.dirname(os.path.abspath(__file__))
#     # 判断系统是iOS，读取iOS_Report__Params.xlsx表
#     if report_os == 'iOS':
#         all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'iOS_Report__Params.xlsx')
#     # 判断系统是Android，读取Android_Report_Params.xlsx表
#     else:
#         all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'Android_Report_Params.xlsx')
#
#     return all_params_filepath
#
#
# # 传入文件路径，广告位id，上报类型，获取对应上报全部参数，如12224 v上报的全部参数
# def get_data_from_excel(all_params_filepath, itemspaceid, reporttype):
#     """
#     从Excel文件中获取指定广告位和上报类型对应的全部参数列表
#
#     :param all_params_filepath: Excel文件路径
#     :param itemspaceid: 广告位ID，用于获取对应的工作表
#     :param reporttype: 上报类型，例如 "v" 或 "av"
#     :return: 全部参数列表
#     """
#     # 打开储存双端广告位+上报类型对应的全部参数的Excel文件
#     workbook = openpyxl.load_workbook(all_params_filepath)
#     # 获取指定的工作表
#     try:
#         # 表里将不同的广告位分分成不同的sheet，根据传入的itemspaceid获取对应sheet表
#         worksheet = workbook[itemspaceid]
#         # 获取工作表的最大列数和行数
#         max_column = worksheet.max_column
#         max_row = worksheet.max_row
#         # 初始化数组，用于存储全部参数
#         all_params = []
#         report_type_column = None  # 初始化 report_type_column 变量为 None
#         # 遍历第一行的每个单元格
#         for column in range(1, max_column + 1):
#             # 获取第一行的每个单元格的值
#             cell_value = worksheet.cell(row=1, column=column).value
#             # 如果单元格的值等于上报类型
#             if cell_value == reporttype:
#                 report_type_column = column  # 获取上报类型所在列的索引
#                 break
#         # 遍历从第二行开始的每一行
#         for row in range(2, max_row + 1):
#             # 获取当前上报类型所在列的全部值
#             cell_value = worksheet.cell(row=row, column=report_type_column).value
#             # 将单元格里不为空的值都存在all_params数组内
#             if cell_value is not None:
#                 all_params.append(cell_value)
#         # 关闭Excel文件
#         workbook.close()
#         return all_params
#     except KeyError:
#         return []

# if real_report_type != 'et':
#     # 判断如果实际上报串内存在广告位id，继续校验
#     if ad_itemspace_id is not None:
#         # 判断如果实际上报串内存在操作系统，继续校验
#         if ad_os is not None:
#             all_params_filepath = get_report_excel(ad_os)
#             # 通过读取的表格，获取对广告位id、上报类型全部上报参数，比如获取12224 v上报的全部参数
#             get_params_config = get_params_config_from_excel(all_params_filepath, ad_itemspace_id, real_report_type)
#             if isinstance(get_params_config, str):
#                 check_result = {
#                     '[校验结果]': '【❌失败】：请在公共参数配置表内配置{}-{}上报需要校验参数'.format(ad_itemspace_id, real_report_type)}
#             else:
#                 all_report_params, important_params, special_params = get_params_config
#                 # 如果获取到的全部参数为空，无法校验
#                 if len(all_report_params) == 0:
#                     check_result = {
#                         '[校验结果]': '【❌失败】：请在公共参数配置表内配置{}-{}上报需要校验参数'.format(ad_itemspace_id, real_report_type)}
#                 else:
#                     # 根据获取到的全部参数，重要参数，以及真实上报参数，调用校验参数函数进行对比，获取到缺失参数、多余参数、已经通过的参数、重要参数、符合预期的值、不符合预期的值
#                     required_params_missing, extra_params, passed_params_sorted, import_passed_params, special_passed_params, right_values, wrong_values = compare_params(
#                         all_report_params, real_report_params, important_params, special_params)
#                     #
#                     #  传入上述获取到的参数，获取当前校验返回结果
#                     output = output_result(required_params_missing, extra_params, passed_params_sorted,
#                                            import_passed_params, special_passed_params, right_values,
#                                            wrong_values)
#                     # # 将广告id和上报类型与校验返回结果组合成最终校验结果
#                     ad_report_tips = get_report_title(real_report_params)
#                     # 通过字典解构操作符 `**` 将 `output` 中的键值对解构并添加到 `check_result` 中，生成最终的校验结果字典
#                     check_result = {ad_report_tips: real_report_type, **output}
#
#         else:
#             check_result = {'[校验结果]': '【❌失败】：os或者sv参数缺失'}
#     else:
#         check_result = {'[校验结果]': '【❌失败】：缺失广告位id'}
# else:
#     ad_report_tips = get_report_title(real_report_params)
#     check_result = {ad_report_tips: real_report_type}


# def get_params_config_from_excel(filepath, worksheet_name, report_event):
#     """
#
#     :param filepath:
#     :param worksheet_name:
#     :param report_event:
#     :return:
#     """
#     # 检查文件路径是否存在
#     if not os.path.exists(filepath):
#         return "文件路径不存在: {}".format(filepath)
#     # 加载工作簿和工作表
#     workbook = openpyxl.load_workbook(filepath)
#     if worksheet_name in workbook.sheetnames:
#         sheet = workbook[worksheet_name]
#         # 获取表头
#         headers = [cell.value for cell in sheet[1]]
#         # 检查上报类型是否存在于表头中
#         if report_event in headers:
#             # 创建表头索引字典 表头值与索引存在一个字典内 例如{'v': 1, None: 9, 'av': 4, 'c': 7}
#             header_index = {header: index + 1 for index, header in enumerate(headers)}
#             # 获取上报类型的列索引，比如v 列索引是1即，第1列，all是1，important是2，special是3
#             report_event_index = header_index[report_event]
#             # 确定数据行起始位置，从第3行开始读，第二行 all，import,special顺序不可变
#             row_start = 3 if sheet.max_row > 1 else 1
#             # 初始化各个列表
#             all_parameters = []
#             important_parameters = []
#             special_parameters = []
#
#             # 遍历每一行，提取对应列的数值,遍历范围从第3行开始，表格最大行结束
#             for row in range(row_start, sheet.max_row + 1):
#                 # 如果v上报列索引是1，则全部参数为第1列，从第3行开始全部列的值
#                 # sheet.cell(row=row, column=report_event_index).value，指定行row和列column返回单元格的值
#                 all_params_value = sheet.cell(row=row, column=report_event_index).value
#                 if all_params_value:
#                     all_parameters.append(all_params_value)
#                 # 如果v上报列索引是1，重要参数为第2列，从第3行开始全部列的值
#                 important_params_value = sheet.cell(row=row, column=report_event_index + 1).value
#                 if important_params_value:
#                     important_parameters.append(important_params_value)
#                 # 如果v上报列索引是1，特殊参数为第3列，从第3行开始全部列的值
#                 special_params_value = sheet.cell(row=row, column=report_event_index + 2).value
#                 if special_params_value:
#                     special_parameters.append(special_params_value)
#             # 将3个列表返回
#             return all_parameters, important_parameters, special_parameters
#         else:
#             return "未找到{}上报类型的参数配置，请配置".format(report_event)
#     else:
#         # 工作表不存在，给出错误提示或执行其他容错处理
#         return "未找到{}上报类型的参数配置，请配置".format(report_event)
#         # 其他容错处理
#
# filepath = r'C:\Users\wenmanwei\PycharmProjects\AutoCheckParams\CheckParams\ReportDataExcel\Event_Report_Params.xlsx'
# worksheet_name='Android'
# re = 'event=6'
# all_parameters, important_parameters, special_parameters = get_params_config_from_excel(filepath, worksheet_name, re)
# print('all:{}'.format(all_parameters))
# print('imp:{}'.format(important_parameters))
# print('sep:{}'.format(special_parameters))

# 备份一下cout逻辑
# def count(request):
#     """
#     校验核心处理逻辑：获取真实上报串，根据上报串获取真实上报类型，判断真实上报串内是否可以获取广告位id和操作系统，再去读取对应全部预期上报参数，调用函数对比，返回校验结果
#
#     :param request:上报请求
#     :return:校验结果
#     """
#     # 获取真实上报串
#     report_url = request.build_absolute_uri()
#     # 获取真实上报类型
#     real_report_type = get_report_type(report_url)
#
#     if request.method == 'POST':
#         post_data = request.body.decode('utf-8')
#         # 将原始数据转换为JSON格式
#         json_data = json.loads(post_data)
#         check_result = json_data
#         check_result = JsonResponse(check_result, json_dumps_params={'ensure_ascii': False})
#     else:
#         # get请求的话，将获取到的上报串参数key与value分割储存到字典内，获取实际上报的全部参数与值
#         real_report_params = {k: v for k, v in request.GET.items()}
#
#         adReportManager = AdReportManager(real_report_params)
#
#         # 从实际上报字典内，获取广告位id，取值itemspaceid或者apid，如果都没有返回none
#         ad_itemspace_id = adReportManager.get_report_itemspaceid()
#
#         # 从实际上报字典内，获取实际操作系统，取值os或者sv，如果都没有返回none
#         ad_os = adReportManager.get_report_ad_os()
#
#         ad_event_value = adReportManager.get_report_event_value()
#         if ad_os is not None:
#             all_params_filepath = get_report_excel(ad_os, real_report_type)
#             if real_report_type != 'et':
#                 if ad_itemspace_id is not None:
#                     get_params_config = get_params_config_from_excel(all_params_filepath, ad_itemspace_id,
#                                                                      real_report_type)
#                 else:
#                     check_result = {'[校验结果]': '【❌失败】：缺失广告位id'}
#                     log_check_result(check_result, report_url)
#                     return JsonResponse(check_result, json_dumps_params={'ensure_ascii': False})
#             else:
#                 get_params_config = get_params_config_from_excel(all_params_filepath, ad_os, ad_event_value)
#
#             print(all_params_filepath)
#             if isinstance(get_params_config, str):
#                 check_result = {
#                     '[校验结果]': '【❌失败】：请在公共参数配置表内配置{}-{}上报需要校验参数'.format(ad_itemspace_id, real_report_type)}
#             else:
#                 all_report_params, important_params, special_params = get_params_config
#                 if len(all_report_params) == 0:
#                     check_result = {
#                         '[校验结果]': '【❌失败】：请在公共参数配置表内配置{}-{}上报需要校验参数'.format(ad_itemspace_id, real_report_type)}
#                 else:
#                     # 根据获取到的全部参数，重要参数，以及真实上报参数，调用校验参数函数进行对比，获取到缺失参数、多余参数、已经通过的参数、重要参数、符合预期的值、不符合预期的值
#                     required_params_missing, extra_params, passed_params_sorted, import_passed_params, special_passed_params, right_values, wrong_values = compare_params(
#                         all_report_params, real_report_params, important_params, special_params)
#                     #
#                     #  传入上述获取到的参数，获取当前校验返回结果
#                     output = output_result(required_params_missing, extra_params, passed_params_sorted,
#                                            import_passed_params, special_passed_params, right_values,
#                                            wrong_values)
#                     # # 将广告id和上报类型与校验返回结果组合成最终校验结果
#                     ad_report_tips = get_report_title(real_report_params)
#                     # 通过字典解构操作符 `**` 将 `output` 中的键值对解构并添加到 `check_result` 中，生成最终的校验结果字典
#                     check_result = {ad_report_tips: real_report_type, **output}
#
#         else:
#             check_result = {'[校验结果]': '【❌失败】：os或者sv参数缺失'}
#
#         log_check_result(check_result, report_url)
#         check_result = JsonResponse(check_result, json_dumps_params={'ensure_ascii': False})
#
#     return check_result


# import json
#
#
# def group_records_by_id(data):
#     output = {}
#     for record in data["data_list"]:
#         id_value = record["uevent"]
#         if f"uevent={id_value}" not in output:
#             output[f"uevent={id_value}"] = []
#         output[f"uevent={id_value}"].append(record)
#     json_output = json.dumps(output)
#     return json_output
#
#
# # 测试
# test = {
#     "data_list": [{
#         "appv": "7.0.6",
#         "build_version": "7.0.6_23.10.18.17",
#         "nwt": "1001",
#         "timetag": "1697790910755",
#         "scene_type": "user",
#         "uevent": "7",
#         "asid": "941bd25f-dcf5-48cc-9dff-079c226b529d_1697790910749",
#         "seq": "1",
#         "launch_id": "0e2e1e74-a8e9-40d5-b8db-e9da48978267",
#         "delayreport": "1"
#     }, {
#         "appv": "7.0.6",
#         "build_version": "7.0.6_23.10.18.17",
#         "nwt": "1001",
#         "timetag": "1697790910962",
#         "scene_type": "user",
#         "uevent": "8",
#         "asid": "941bd25f-dcf5-48cc-9dff-079c226b529d_1697790910749",
#         "seq": "2",
#         "launch_id": "0e2e1e74-a8e9-40d5-b8db-e9da48978267",
#         "delayreport": "1"
#     }, {
#         "appv": "7.0.6",
#         "build_version": "7.0.6_23.10.18.17",
#         "nwt": "1001",
#         "timetag": "1697790910967",
#         "scene_type": "user",
#         "uevent": "11",
#         "asid": "941bd25f-dcf5-48cc-9dff-079c226b529d_1697790910749",
#         "seq": "3",
#         "page_event_id": "Y29tLnNvaHUubmV3c2NsaWVudC5ib290LmFjdGl2aXR5LlNwbGFzaEFjdGl2aXR5",
#         "launch_id": "0e2e1e74-a8e9-40d5-b8db-e9da48978267",
#         "delayreport": "1"
#     }, {
#         "scene_type": "mat",
#         "uevent": "24",
#         "asid": "941bd25f-dcf5-48cc-9dff-079c226b529d_1697790910749",
#         "appv": "7.0.6",
#         "build_version": "7.0.6_23.10.18.17",
#         "nwt": "1001",
#         "timetag": "1697790910978",
#         "mat_md5list": "[{\"md5\":\"c4a68c0c4b3bc9f0c88a061812da076a\",\"time\":\"1697854650000\",\"type\":\"zip\"},{\"md5\":\"631cac67217d27abe2d61d49c3c0dfcf\",\"time\":\"1697854651000\",\"type\":\"jpg\"},{\"md5\":\"c2ae576a1b9718cd3c7797bf94ac5420\",\"time\":\"1697854651000\",\"type\":\"mp4\"},{\"md5\":\"a5be40297812ebbcac18c6b60e01a1b8\",\"time\":\"1697853658000\",\"type\":\"zip\"},{\"md5\":\"4a10faebacf8c6ccae6345f969132700\",\"time\":\"1697853645000\",\"type\":\"zip\"},{\"md5\":\"acf9d2aa7eb1d0756f655b45508281f3\",\"time\":\"1697853658000\",\"type\":\"zip\"},{\"md5\":\"04d42c0ffbc8c3307ebd75147c456ad1\",\"time\":\"1697853658000\",\"type\":\"zip\"},{\"md5\":\"528ab91645252912f7fb129729493a1c\",\"time\":\"1697853650000\",\"type\":\"zip\"},{\"md5\":\"697ea4b0e43a55a1d8a15803bd6b4355\",\"time\":\"1697853648000\",\"type\":\"zip\"},{\"md5\":\"5fe1af520f8710f7c45662d013d02153\",\"time\":\"1697853645000\",\"type\":\"zip\"},{\"md5\":\"2f132d4e4417fa16e636a7a58a42fe9b\",\"time\":\"1697853648000\",\"type\":\"zip\"},{\"md5\":\"0d8a52d95056023633d4c48fd88b52d1\",\"time\":\"1697853646000\",\"type\":\"zip\"},{\"md5\":\"b11b7c0afc77c85aa2e5b275b8879ab0\",\"time\":\"1697853655000\",\"type\":\"zip\"},{\"md5\":\"e96488c44b238d3fc2d899371a069a27\",\"time\":\"1697853656000\",\"type\":\"zip\"},{\"md5\":\"bdc707e18b6dc2768053d99d71ede419\",\"time\":\"1697853662000\",\"type\":\"zip\"},{\"md5\":\"b0618da0d2d8550bf344c83c7508af87\",\"time\":\"1697853661000\",\"type\":\"mp4\"},{\"md5\":\"b36c71d36602dad0569cd2bb6a41b76d\",\"time\":\"1697853662000\",\"type\":\"zip\"},{\"md5\":\"3480e590be9bdc9914a2d9ecbc27b0a9\",\"time\":\"1697853666000\",\"type\":\"zip\"},{\"md5\":\"483be9188b3ffdfbcfa7fda02e01cc9f\",\"time\":\"1697853647000\",\"type\":\"zip\"},{\"md5\":\"726d67259d5c6b368570dbbb4f2d6188\",\"time\":\"1697853662000\",\"type\":\"zip\"},{\"md5\":\"d9b419885543ff0570294ecf61f925c5\",\"time\":\"1697853656000\",\"type\":\"zip\"},{\"md5\":\"58359e01b737e8305eca850f59408b55\",\"time\":\"1697853649000\",\"type\":\"zip\"},{\"md5\":\"2d0bb6a33e9a6c4abfe6f82ee71b7f8e\",\"time\":\"1697853650000\",\"type\":\"zip\"},{\"md5\":\"eaf22835990fd0480a5ae6eb7d85594c\",\"time\":\"1697853655000\",\"type\":\"zip\"},{\"md5\":\"d67d74fc749196e428e9dfb82e011882\",\"time\":\"1697853659000\",\"type\":\"mp4\"},{\"md5\":\"2082831eb385d04c8093e28b4b1acb62\",\"time\":\"1697853658000\",\"type\":\"zip\"},{\"md5\":\"6b5086bdb45c3063a28204131336107b\",\"time\":\"1697853659000\",\"type\":\"zip\"}]",
#         "delayreport": "1"
#     }]}
#
# output = group_records_by_id(test)
#
# print(output)


# def get_keys(dictionary):
#     keys = []
#     for key, value in dictionary.items():
#         keys.append(key)
#         if isinstance(value, dict):
#             keys.extend(get_keys(value))
#
#     return keys
#
#
# testa = {
#     "uevent=7": [
#         {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}},
#         {"a": "ad", "uevent": "7", "wwm": {"mmm": "1223", "www": "32221"}}
#     ]
# }
#
# event_7_data = testa.get("uevent=7", [])
#
# for item in event_7_data:
#     keys = get_keys(item)
#     print(keys)


# def compare_keys(testa, testb):
#     expected_keys = set(testa)
#     actual_keys = set(testb.keys())
#
#     # Check missing parameters
#     missing_keys = expected_keys - actual_keys
#
#     # Check redundant parameters
#     redundant_keys = actual_keys - expected_keys
#
#     print(f"预期的参数集合: {', '.join(expected_keys)}")
#     print(f"实际的参数集合: {', '.join(actual_keys)}")
#     print(f"缺失的参数: {', '.join(missing_keys)}")
#     print(f"冗余的参数: {', '.join(redundant_keys)}")
#
# testa = ["uevent", "a", "wwm", "mmm", "www", "rongyu"]
# testb = {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}}
#
# compare_keys(testa, testb)


# def count_uevent(data):
#     result = {}
#     for item in data["data_list"]:
#         uevent = item["uevent"]
#         if uevent in result:
#             result[uevent]["详情如下"].append(item)
#         else:
#             result[uevent] = {"详情如下": [item]}
#
#     final_result = {}
#     for uevent, details in result.items():
#         count = len(details["详情如下"])
#         final_result[f"uevent={uevent}事件共{count}个"] = details
#
#     return final_result
#
#
# # 测试数据
# data = {
#     "data_list": [
#         {"type": "user", "asid": "9", "uevent": "7"},
#         {"type": "user", "asid": "19", "uevent": "7"},
#         {"type": "user", "asid": "19", "uevent": "11"},
#         {"type": "us1er", "asid": "19", "uevent": "11"}
#     ]
# }
#
# result = count_uevent(data)
# print(result)
# import json
#
# data = {
#     "data_list": [
#         {
#             "type": "user",
#             "asid": "9",
#             "uevent": "7"
#         },
#         {
#             "type": "user",
#             "asid": "19",
#             "uevent": "7"
#         },
#         {
#             "type": "user",
#             "asid": "19",
#             "uevent": "11"
#         },
#         {
#             "type": "us1er",
#             "asid": "19",
#             "uevent": "11"
#         }
#     ]
# }
#
# result = {}
#
# for item in data["data_list"]:
#     uevent = item["uevent"]
#     if uevent in result:
#         result[uevent].append(item)
#     else:
#         result[uevent] = [item]
#
# output = {}
# for key, value in result.items():
#     output[f"uevent={key}事件共{len(value)}个"] = {f"uevent={key}": value}
#
# output_json = json.dumps(output, indent=4)
# print(output)


# import json
#
# def count_uevent(data):
#     result = {}
#
#     for item in data["data_list"]:
#         uevent = item["uevent"]
#         if uevent in result:
#             result[uevent].append(item)
#         else:
#             result[uevent] = [item]
#
#     output = {}
#     for key, value in result.items():
#         output[f"uevent={key}事件共{len(value)}个"] = {f"uevent={key}": value}
#
#     return json.dumps(output, ensure_ascii=False, indent=4)
#
# data = {
#     "data_list": [
#         {
#             "type": "user",
#             "asid": "9",
#             "uevent": "7"
#         },
#         {
#             "type": "user",
#             "asid": "19",
#             "uevent": "7"
#         },
#         {
#             "type": "user",
#             "asid": "19",
#             "uevent": "11"
#         },
#         {
#             "type": "us1er",
#             "asid": "19",
#             "uevent": "11"
#         }
#     ]
# }
#
# output_json = count_uevent(data)
# print(output_json)

# import json
#
# def count_uevent(data):
#     result = {}
#
#     for item in data["data_list"]:
#         uevent = item["uevent"]
#         if uevent in result:
#             result[uevent].append(item)
#         else:
#             result[uevent] = [item]
#
#     output = {}
#     sorted_uevents = sorted(result.keys(), key=lambda x: int(x))
#     for uevent in sorted_uevents:
#         value = result[uevent]
#         output[f"uevent={uevent}"] = {f"uevent={uevent}": value}
#         output[f"uevent={uevent}事件共{len(value)}个"] = {f"uevent={uevent}": value}
#
#     return json.dumps(output, ensure_ascii=False, indent=4)
#
# data = {
#     "data_list": [
#         {
#             "type": "user",
#             "asid": "9",
#             "uevent": "7"
#         },
#         {
#             "type": "user",
#             "asid": "19",
#             "uevent": "7"
#         },
#         {
#             "type": "user",
#             "asid": "19",
#             "uevent": "11"
#         },
#         {
#             "type": "user",
#             "asid": "19",
#             "uevent": "11"
#         }
#     ]
# }
#
# output_json = count_uevent(data)
# print(output_json)
# def group_by_uevent(data_list):
#     result = {}
#
#     for item in data_list:
#         uevent = item["uevent"]
#         if uevent not in result:
#             result[uevent] = {
#                 f"uevent={uevent}事件总数为": "0",
#                 "details": []
#             }
#         result[uevent]["details"].append(item)
#
#     for uevent, info in result.items():
#         info[f"uevent={uevent}事件总数为"] = str(len(info["details"]))
#
#     return result
#
#
# data_list = [
#     {
#         "type": "user",
#         "asid": "9",
#         "uevent": "7"
#     },
#     {
#         "type": "user",
#         "asid": "19",
#         "uevent": "7"
#     },
#     {
#         "type": "user",
#         "asid": "19",
#         "uevent": "11"
#     },
#     {
#         "type": "us1er",
#         "asid": "19",
#         "uevent": "11"
#     }
# ]
#
# result = group_by_uevent(data_list)
# final_result = json.dumps(result, indent=4)
# print(final_result)
#
# def group_by_uevent(data_list):
#     result = {}
#
#     for item in data_list:
#         uevent = item["uevent"]
#         if "uevent=" + uevent not in result:
#             result["uevent=" + uevent] = {
#                 f"uevent={uevent}事件总数为": "0",
#                 "details": []
#             }
#         result["uevent=" + uevent]["details"].append(item)
#
#     for uevent, info in result.items():
#         info[f"uevent={uevent}事件总数为"] = str(len(info["details"]))
#
#     return result
#
# data_list = [
#     {
#         "type": "user",
#         "asid": "9",
#         "uevent": "7"
#     },
#     {
#         "type": "user",
#         "asid": "19",
#         "uevent": "7"
#     },
#     {
#         "type": "user",
#         "asid": "19",
#         "uevent": "11"
#     },
#     {
#         "type": "us1er",
#         "asid": "19",
#         "uevent": "11"
#     }
# ]
#
# result = group_by_uevent(data_list)
# final_result = json.dumps(result, indent=4)
# print(final_result)

# uet校验

# def compare_keys(testa, testb):
#     expected_keys = set(testa)
#     for i, item in enumerate(testb["uevent=7"]["details"]):
#         actual_keys = set()
#         for key, value in item.items():
#             actual_keys.add(key)
#             if isinstance(value, dict):
#                 actual_keys.update(value.keys())
#
#         # Check missing parameters
#         missing_keys = expected_keys - actual_keys
#         print(actual_keys)
#         print(expected_keys)
#
#         expected = actual_keys.intersection(expected_keys)
#         # Check redundant parameters
#         redundant_keys = actual_keys - expected_keys
#
#         print(f"testb[\"uevent=7\"][{i}]符合预期的是：{', '.join(expected)}")
#         print(f"缺失的是：{', '.join(missing_keys)}")
#         print(f"冗余参数：{', '.join(redundant_keys)}")
#         print()
#
#
# testa = ["uevent", "a", "wwm", "mmm", "www", "rongyu"]
#
# testb = {
#     "uevent=7": {"details": [
#         {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}},
#         {"a": "ad", "uevent": "7", "wwm": {"mmm": "1223", "www": "32221"}}
#     ]},
#     "uevent=8": {"details": [
#         {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}},
#         {"a": "ad", "uevent": "7", "wwm": {"mmm": "1223", "www": "32221"}}
#     ]}
# }
#
# compare_keys(testa, testb)


# def compare_keys(testa, testb, uevent_key):
#     expected_keys = set(testa)
#     for i, item in enumerate(testb[uevent_key]["details"]):
#         actual_keys = set(item.keys())
#         for key, value in item.items():
#             if isinstance(value, dict):
#                 actual_keys.update(value.keys())
#
#         # Check missing parameters
#         missing_keys = expected_keys - actual_keys
#
#         # Check redundant parameters
#         redundant_keys = actual_keys - expected_keys
#
#         print(f"testb[{uevent_key}][\"details\"][{i}]符合预期的是：{', '.join(expected_keys)}")
#         print(f"缺失的是：{', '.join(missing_keys)}")
#         print(f"冗余参数：{', '.join(redundant_keys)}")
#         print()
#
#
# testa = ["uevent", "a", "wwm", "mmm", "www", "rongyu"]
# testb = {
#     "uevent=7": {"details": [
#         {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}},
#         {"a": "ad", "uevent": "7", "wwm": {"mmm": "1223", "www": "32221"}}
#     ]},
#     "uevent=8": {"details": [
#         {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}},
#         {"a": "ad", "uevent": "7", "wwm": {"mmm": "1223", "www": "32221"}}
#     ]}
# }
#
# user_input = input("请输入要对比的键（uevent=7或uevent=8）：")
#
# if user_input == "uevent=7":
#     compare_keys(testa, testb, "uevent=7")
# elif user_input == "uevent=8":
#     compare_keys(testa, testb, "uevent=8")
# import json


# def compare_keys(testa, testb, uevent_key):
#     expected_keys = set(testa)
#
#     result = {}
#
#     for i, item in enumerate(testb[uevent_key]["details"]):
#         actual_keys = set()
#         for key, value in item.items():
#             actual_keys.add(key)
#             if isinstance(value, dict):
#                 actual_keys.update(value.keys())
#
#         # Check missing parameters
#         missing_keys = expected_keys - actual_keys
#
#         expected = actual_keys.intersection(expected_keys)
#         # Check redundant parameters
#         redundant_keys = actual_keys - expected_keys
#         comparison_result = {
#             "缺失参数": list(missing_keys),
#             "冗余参数": list(redundant_keys)
#         }
#         missing_counts = len(missing_keys)
#         redundant_counts = len(redundant_keys)
#
#         if missing_counts > 0 or redundant_counts > 0:
#             if missing_counts > 0 and redundant_counts > 0:
#                 result[f"{uevent_key}[{i}]校验失败，存在缺失和冗余参数--->"] = comparison_result
#             if missing_counts > 0 and redundant_counts == 0:
#                 keys_to_remove = ['冗余参数']
#                 for key in keys_to_remove:
#                     comparison_result.pop(key)
#                 result[f"{uevent_key}[{i}]校验失败，存在缺失参数--->"] = comparison_result
#
#             if missing_counts == 0 and redundant_counts > 0:
#                 keys_to_remove = ['缺失参数']
#                 for key in keys_to_remove:
#                     comparison_result.pop(key)
#                 result[f"{uevent_key}[{i}]校验失败，存在冗余参数--->"] = comparison_result
#
#     return result

# from collections import OrderedDict
# def group_by_uevent(data):
#     """
#
#     :param data: uet 完整上报内容
#     :return: 校验结果
#     """
#     result = OrderedDict()
#
#     for item in data_list["data_list"]:
#         uevent = item["uevent"]
#         if "uevent=" + uevent not in result:
#             a = "chenggong"
#             if a == "chenggong":
#                 result["uevent=" + uevent] = {
#                     f"uevent={uevent}事件总数为": "0",
#                     f"uevent={uevent}校验结果-->成功": "",
#                     "details": []
#                 }
#             else:
#                 result["uevent=" + uevent] = {
#                     f"uevent={uevent}事件总数为": "0",
#                     f"uevent={uevent}校验结果-->失败": {},
#                     "details": []
#                 }
#         result["uevent=" + uevent]["details"].append(item)
#     for uevent, info in result.items():
#
#
#         info[f"{uevent}事件总数为"] = str(len(info["details"]))
#
#     sorted_result = dict(sorted(result.items(), key=lambda x: int(x[0].split("=")[1])))  # 根据事件号排序结果字典
#
#     final_result = json.dumps(sorted_result, indent=4, ensure_ascii=False)  # 将排序后的字典转换为JSON格式字符串
#     return final_result
#
# data_list = {
#     "data_list": [{
#         "scene_type": "user",
#         "asid": "7EC95DB8-D95A-43B6-B979-3C4AAB374F58_1698059957378",
#         "uevent": "7",
#         "timetag": "1698059957439",
#         "nwt": "1001",
#         "build_version": "7.0.60.224.1",
#         "launch_id": "B2C40E69-321C-404B-A024-8738A34D3BFE",
#         "appv": "7.0.6",
#         "seq": "1"
#     }, {
#         "scene_type": "user",
#         "asid": "7EC95DB8-D95A-43B6-B979-3C4AAB374F58_1698059957378",
#         "uevent": "11",
#         "seq": "2",
#         "timetag": "1698059957520",
#         "nwt": "1001",
#         "build_version": "7.0.60.224.1",
#         "launch_id": "B2C40E69-321C-404B-A024-8738A34D3BFE",
#         "appv": "7.0.6",
#         "page_event_id": "U05Sb2xsaW5nTmV3c1ZpZXdDb250cm9sbGVy"
#     }, {
#         "scene_type": "user",
#         "asid": "7EC95DB8-D95A-43B6-B979-3C4AAB374F58_1698059957378",
#         "uevent": "11",
#         "appv": "7.0.6",
#         "timetag": "1698059957521",
#         "seq": "3",
#         "nwt": "1001",
#         "build_version": "7.0.60.224.1",
#         "refer": "U05Sb2xsaW5nTmV3c1ZpZXdDb250cm9sbGVy",
#         "launch_id": "B2C40E69-321C-404B-A024-8738A34D3BFE",
#         "page_event_id": "U0NOQURTcGxhc2hWaWV3Q29udHJvbGxlcg=="
#     }, {
#         "scene_type": "user",
#         "asid": "7EC95DB8-D95A-43B6-B979-3C4AAB374F58_1698059957378",
#         "uevent": "8",
#         "timetag": "1698059957526",
#         "nwt": "1001",
#         "build_version": "7.0.60.224.1",
#         "launch_id": "B2C40E69-321C-404B-A024-8738A34D3BFE",
#         "appv": "7.0.6",
#         "seq": "4"
#     }, {
#         "scene_type": "user",
#         "asid": "7EC95DB8-D95A-43B6-B979-3C4AAB374F58_1698059957378",
#         "uevent": "12",
#         "appv": "7.0.6",
#         "timetag": "1698059962885",
#         "seq": "5",
#         "nwt": "1001",
#         "build_version": "7.0.60.224.1",
#         "refer": "U05Sb2xsaW5nTmV3c1ZpZXdDb250cm9sbGVy",
#         "launch_id": "B2C40E69-321C-404B-A024-8738A34D3BFE",
#         "page_event_id": "U0NOQURTcGxhc2hWaWV3Q29udHJvbGxlcg=="
#     }, {
#         "scene_type": "user",
#         "asid": "7EC95DB8-D95A-43B6-B979-3C4AAB374F58_1698059957378",
#         "uevent": "9",
#         "timetag": "1698060030284",
#         "nwt": "1001",
#         "build_version": "7.0.60.224.1",
#         "launch_id": "B2C40E69-321C-404B-A024-8738A34D3BFE",
#         "appv": "7.0.6",
#         "seq": "6"
#     }]
# }
#
# result = group_by_uevent(data_list)

# print(result)
# def compare_uet_keys(testa, testb, uevent_key):
#     expected_keys = set(testa)
#
#     fail_result = {
#                 f"{uevent_key}校验结果-->失败": {
#                     "失败原因": "存在冗余参数",
#                     "校验详情":[]
#                 }
#             }
#     sucess_result = {
#                 f"{uevent_key}校验结果-->成功": "参数不多不少"
#             }
#     for i, item in enumerate(testb[uevent_key]["details"]):
#         actual_keys = set()
#         for key, value in item.items():
#             actual_keys.add(key)
#             if isinstance(value, dict):
#                 actual_keys.update(value.keys())
#         missing_keys = expected_keys - actual_keys
#         expected = actual_keys.intersection(expected_keys)
#         redundant_keys = actual_keys - expected_keys
#         if missing_keys or redundant_keys:
#             comparison_result = {
#                 "缺失参数": list(missing_keys),
#                 "冗余参数": list(redundant_keys)
#             }
#
#             if missing_keys and redundant_keys:
#                 fail_result[f"{uevent_key}校验结果-->失败"]["校验详情"].append({f"{uevent_key}[{i}]校验详情--->": comparison_result})
#                 result = fail_result
#             elif missing_keys:
#                 comparison_result.pop("冗余参数", None)
#                 fail_result[f"{uevent_key}校验结果-->失败"]["校验详情"].append({f"{uevent_key}[{i}]校验详情--->": comparison_result})
#                 result = fail_result
#             else:
#                 comparison_result.pop("缺失参数", None)
#                 fail_result[f"{uevent_key}校验结果-->失败"]["校验详情"].append({f"{uevent_key}[{i}]校验详情--->": comparison_result})
#                 result = fail_result
#         else:
#             result = sucess_result
#
#     return result
#
#
#
# # testa = ["uevent", "a", "wwm", "mmm", "www", "rongyu"]
# testb = {
#     "uevent=7": {"details": [
#         {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}},
#         {"a": "ad", "uevent": "7", "wwm": {"mmm": "1223", "www": "32221"}}
#     ]},
#     "uevent=8": {"details": [
#         {"a": "user", "uevent": "7", "wwm": {"hahaha": "123", "www": "321"}},
#         {"a": "ad", "uevent": "7", "wwm": {"mmm": "1223", "www": "32221"}}
#     ]}
# }
# testa = ["scene_type", "asid", "uevent", "timetag", "nwt", "build_version", "launch_id", "appv", "seq"]
# uevent_key="uevent=8"
# compare_uet_keys(testa, testb, uevent_key)
# print(compare_uet_keys(testa, testb, uevent_key))
# def get_report_excel(report_os=None, report_type=None):
#     """
#     根据操作系统读取本地储存的参数表
#     :param report_type:
#     :param report_os:上报操作系统
#     :return:all_params_filepath
#     """
#     current_dir = os.path.dirname(os.path.abspath(__file__))
#     # 判断系统是iOS，读取iOS_Report__Params.xlsx表
#     if report_type == 'et':
#         all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'Event_Report_Params.xlsx')
#     elif report_type == 'uet':
#         all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'Uevent_Report_Params.xlsx')
#     else:
#         if report_os == 'iOS':
#             all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'iOS_Report__Params.xlsx')
#         # 判断系统是Android，读取Android_Report_Params.xlsx表
#         elif report_os == 'Android':
#             all_params_filepath = os.path.join(current_dir, 'ReportDataExcel', 'Android_Report_Params.xlsx')
#
#     return all_params_filepath
#
# get_report_excel(None,'uet')
# print(get_report_excel(None, 'uet')
#
# )


# def check_dict_for_mouse(dic):
#     for value in dic.values():
#         if isinstance(value, dict):
#             if check_dict_for_mouse(value):
#                 return True
#         elif value == 'mouse':
#             return True
#     return False
#
# dict = {
#   'ob1': 'computer',
#   'ob2': {
#     'sub_ob1': 'keyboard',
#     'sub_ob2': {
#       'sub_sub_ob1': 'mouse'
#     }
#   },
#   'ob3': 'printer'
# }
#
# if check_dict_for_mouse(dict):
#     print('mouse')


import re


# data = [{
#     "uevent=7事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]",
#     "uevent=7事件共上报[2]条": "校验通过[1]条，失败[0]条--------[success]"
# }, {
#     "uevent=11事件共上报[14]条": "校验通过[14]条，失败[0]条--------[success]"
# }, {
#     "uevent=8事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]"
# }, {
#     "uevent=12事件共上报[13]条": "校验通过[13]条，失败[0]条--------[success]"
# }, {
#     "uevent=1事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]"
# }, {
#     "uevent=2事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]"
# }, {
#     "uevent=4事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]"
# }, {
#     "uevent=5事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]"
# }, {
#     "uevent=9事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]"
# }, {
#     "uevent=10事件共上报[1]条": "校验通过[1]条，失败[0]条--------[success]"
# }]
#
# aa = data[0].values()
# print(aa)
# sorted_data = sorted(data, key=lambda x: int(re.search(r'\d+', list(x.keys())[0]).group()))
#
# print(sorted_data)

# def compare_uet_params(config_all_uet_params, real_report_uet_params, uevent_type):
#     """
#     uet参数校验，检验uevent事件参数缺失情况
#     :param config_all_uet_params: 本地表内uevent上报事件参数，数组类型
#     :param real_report_uet_params: 真实上报uevent参数归类详情，原始数据加工处理成 每个uevent数据被存储在{‘uevent=x’:{'details'}:[...]}数组内，意图是方便校验该事件的每一条上报数据
#     :param uevent_type: 事件类型，例如uevent=x
#     :return: uet_compare_result校验结果，成功或者失败的字典
#     """
#     # 初始化uet_compare_result为uet最终校验结果
#     uet_compare_result = ''
#     expected_keys = set(config_all_uet_params)
#     fail_result = {
#         f"[{uevent_type}事件-校验结果]-->失败": {
#             "失败原因": "存在冗余参数",
#             "失败详情": []
#         }
#     }
#     success_result = {
#         f"[{uevent_type}事件-校验结果]-->成功": "参数不多不少"
#     }
#
#     for i, item in enumerate(real_report_uet_params[uevent_type]["details"]):
#         actual_keys = set()
#         print(i, item)
#         for key, value in item.items():
#             actual_keys.add(key)
#             if isinstance(value, dict):
#                 actual_keys.update(value.keys())
#
#         missing_params = expected_keys - actual_keys
#         redundant_params = actual_keys - expected_keys
#         # expected = actual_keys.intersection(expected_keys)
#         if uevent_type in ['uevent=7', 'uevent=8', 'uevent=9', 'uevent=10', 'uevent=11', 'uevent=12']:
#             ignore_params = {'page_event_id', 'refer'}
#             missing_params.difference_update(ignore_params)
#
#         comparison_result = {
#             "缺失参数": list(missing_params),
#             "冗余参数": list(redundant_params)
#         }
#         if missing_params or redundant_params:
#             if missing_params and redundant_params:
#                 fail_result[f"[{uevent_type}事件-校验结果]-->失败"]["失败原因"] = "存在缺失和冗余参数，请查看详情"
#
#             elif missing_params:
#                 comparison_result.pop("冗余参数", None)
#                 fail_result[f"[{uevent_type}事件-校验结果]-->失败"]["失败原因"] = "存在缺失参数，请查看详情"
#
#             elif redundant_params:
#                 comparison_result.pop("缺失参数", None)
#                 fail_result[f"[{uevent_type}事件-校验结果]-->失败"]["失败原因"] = "存在冗余参数，请查看详情"
#
#             fail_result[f"[{uevent_type}事件-校验结果]-->失败"]["失败详情"].append(
#                 {f"[{uevent_type}[{i}]事件-校验详情]--->": comparison_result})
#
#         uet_compare_result = fail_result if missing_params or redundant_params else success_result
#
#     return uet_compare_result
#
#
# config_all_uet_params = r'C:\Users\wenmanwei\PycharmProjects\AutoCheckParams\CheckParams\ReportDataExcel\Uevent_Report_Params.xlsx'
# ddd = {
#     'uevent=7': {
#         '[事件名称]': 'APP启动-冷启动',
#         '[上报时机]': '[1]-app进入-冷启动;[2]-Push进入（已杀进程）;[3]-端外呼起（已杀进程）', '[uevent=7事件-上报总数]': 0,
#         'details': [{'scene_type': 'user', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_1698284550358', 'uevent': '7',
#                      'timetag': '1698284550425', 'nwt': '1001', 'build_version': '7.0.60.224.1',
#                      'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149', 'appv': '7.0.6', 'seq': '1'}]},
#     'uevent=8': {
#         '[事件名称]': 'APP启动-后台进入前台',
#         '[上报时机]': '[1]-app进入后台再返回;[2]-Push进入（未杀进程）;[3]-端外呼起（未杀进程）;[4]-app进入-热启动（仅安卓）;[5]-锁屏再打开;[6]-下拉通知栏返回,会同时上报三个事件，uet=8,9,8（仅iOS）',
#         '[uevent=8事件-上报总数]': 0,
#         'details': [{'scene_type': 'user', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_1698284550358', 'uevent': '8',
#                      'timetag': '1698284550511', 'nwt': '1001', 'build_version': '7.0.60.224.1',
#                      'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149', 'appv': '7.0.6', 'seq': '2'}]},
#     'uevent=11': {
#         '[事件名称]': '用户页面进入',
#         '[上报时机]': '[1]-进入信息流频道页;[2]-进入信息流频道页;[3]-进入视频播放详情页;[4]-进入话题阅读版页面;[5]-进入负一屏速览[6]-进入热榜tab（仅iOS）',
#         '[uevent=11事件-上报总数]': 0,
#         'details': [{'scene_type': 'user', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_1698284550358', 'uevent': '11',
#                      'seq': '3', 'timetag': '1698284550515', 'nwt': '1001', 'build_version': '7.0.60.224.1',
#                      'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149', 'appv': '7.0.6',
#                      'page_event_id': 'U05Sb2xsaW5nTmV3c1ZpZXdDb250cm9sbGVy'},
#                     {'scene_type': 'user', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_169550358', 'uevent': '11',
#                      'appv': '7.0.6', 'timetag': '1698284550523', 'seq': '4', 'nwt': '1001',
#                      'build_version': '7.0.60.224.1', 'refer': 'U05Sb2xsaW5nTmV3c1ZpZXdDb250cm9sbGVy',
#                      'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149',
#                      'page_event_id': 'U0NOQURTcGxhc2hWaWV3Q29udHJvbGxlcg=='}]},
#     'uevent=12': {
#         '[事件名称]': '用户页面退出',
#         '[上报时机]': '[1]-退出信息流频道页;[2]-退出文章页;[3]-退出视频播放详情页;[4]-退出话题阅读版页面;[5]-退出负一屏速览卡;[6]-退出热榜tab;[7]-退出我的页面，退出我的页面（仅iOS）',
#         '[uevent=12事件-上报总数]': 0,
#         'details': [{'scene_type': 'user', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_1698284550358', 'uevent': '12',
#                      'appv': '7.0.6', 'timetag': '1698284553907', 'seq': '5', 'nwt': '1001',
#                      'build_version': '7.0.60.224.1', 'refer': 'U05Sb2xsaW5nTmV3c1ZpZXdDb250cm9sbGVy',
#                      'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149',
#                      'page_event_id': 'U0NOQURTcGxhc2hWaWV3Q29udHJvbGxlcg=='}]},
#     'uevent=9': {
#         '[事件名称]': 'APP退出-放后台',
#         '[上报时机]': '[1]-app退出-切后台;[2]-app退出-双击back（仅安卓）;[3]-锁屏;[4]-点广告呼起其他app;[5]-下拉工具栏（仅安卓）;[6]-下拉通知栏（仅iOS）',
#         '[uevent=9事件-上报总数]': 0,
#         'details': [{'scene_type': 'user', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_1698284550358', 'uevent': '9',
#                      'timetag': '1698284613347', 'nwt': '1001', 'build_version': '7.0.60.224.1',
#                      'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149', 'appv': '7.0.6', 'seq': '6'}]},
#     'uevent=10': {
#         '[事件名称]': 'APP退出（杀进程）',
#         '[上报时机]': 'app退出-杀进程',
#         '[uevent=10事件-上报总数]': 0,
#         'details': [{'scene_type': 'user', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_1698284550358', 'uevent': '10',
#                      'timetag': '1698284614138', 'nwt': '1001', 'build_version': '7.0.60.224.1',
#                      'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149', 'appv': '7.0.6', 'seq': '7'}]}}


# def check_report_params_value(passed_params):
#     """
#     用于处理常规上报校验通过参数的值
#     :param passed_params: 校验通过的参数，继续校验取值
#     :return:返回符合预期与不符合预期的参数以及值
#     """
#     # 定义预期值字典，使用字典的值存储预期值和预期信息
#     expected_values = {
#         'appchn': ([r'^\d{4}$'], 'appchn-渠道号，取值4位数'),  # 使用列表存储正则表达式和预期信息
#         'appid': (['news'], 'appid固定取值news'),  # 使用列表存储字符串和预期信息
#         'appv': ([r'\d+\.\d+\.\d+'], 'appv-版本号，取值x.y.z '),  # 使用列表存储正则表达式和预期信息
#         'asid': ([r'^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}_\d{13}$'],
#                  'asid-启动标识，取值id+时间戳(开发生成)'),
#         'abposition': ([r'^\d+$'], 'abposition-广告位置，取值数字'),
#         'adstyle': (['1', '2'], 'adstyle-软文应该标识，取值0或1(=1硬广,=2软文)'),
#         'apid': ([r'^\d{5}$'], 'apid取值广告位id'),
#         'ad_abtest': ([r'^$', r'\S'], 'ad_abtest值无需关注'),
#         'appdelaytrack': (['0', '1'], 'appdelaytrack-缓存标识,取值0或1(=0非缓存，=1缓存)'),
#         'ac': ([r'^\d+$'], 'ac重复展示标识，=1或者正常累加'),
#         'build_version': ([r'(\d+\.\d+\.\d+)_(\d+\.\d+\.\d+\.\d+)', r'^(\d+)\.(\d+)\.(\d+)\.(\d+)\.(\d+)$',
#                            r'^(\d+)\.(\d+)\.(\d+)\.(\d+)$'],
#                           'build_version-客户端打包版本号(Android：appv_构建年月日打包次数_渠道号,iOS：appv.build号)'),
#         'cid': ([r'^\d{19}$'], 'cid-用户id,算法生成19位数字'),
#         'cacheNum': ([r'^\d+$'], 'cacheNum-联盟缓可用缓存数'),
#         'cacheUT': ([r'\d{13}'], 'cacheUT-上次有效更新缓存时间戳'),
#         'clickmonitor': (['c', r'^$'], 'clickmonitor取值c或空'),
#         'coldstart': (['0', '1'], 'coldstart-是否冷启,取值0=热启,=1冷启'),
#         'deeplink': (['0', '1'], 'deeplink-创意呼起开关,取值0或1(=0打开，=1关闭)'),
#         'dytype': (['0', '1', '2', r'^$'], 'dytype-多赢类型，取值=0普通广告,=1时刻阅读版,=2媒体号'),
#         'delaytrack': (['0', '1'], 'delaytrack-重试上报标识,取值0或1，=0首次上报，=1重试上报'),
#         'errorcode': (['0', '1'], 'errorcode-重试上报标识,取值0或1，=0首次上报，=1重试上报'),
#         'event': ([r'^\d+$'], 'event-et上报事件类型'),
#         'gbcode': ([r'^\d{10}$', r'^\d{6}$'], 'gbcode-地域编码,取值10位地域编码'),
#         'h': ([r'^$', r'\S'], 'h值无需关注'),
#         'itemspaceid': ([r'\d{5}'], 'itemspaceid-广告位id)'),
#         'impid': ([r'\S'], 'impid-广告请求唯一标识(取值引擎生成，不可为空)'),
#         'impressionid': ([r'\S'], 'impressionid-广告请求唯一标识,取值引擎生成，不可为空'),
#         'landing': (['0', '1', '2', '3'], 'landing-落地页加载状态，取值=0开始加载,=1完成加载,=2加载失败,=3离开'),
#         'lc': ([r'^\d+$'], 'lc-加载次数，取值数字'),
#         'local': (['0', '1'], 'landing-落地页加载状态，取值=0开始加载,=1完成加载,=2加载失败,=3离开'),
#         'login_pid': ([r'^\d{19}$', r'^$'], 'login_pid-搜狐新闻登录用户的id,取值用户端pid'),
#         'launch_id': (
#             [r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'], 'launch_id-冷启动唯一标识'),
#         'mkey': ([r'\S'], 'mkey广告请求唯一标识(取值引擎生成，不可为空)'),
#         'monitorkey': ([r'\S'], 'mkey广告请求唯一标识(取值引擎生成，不可为空)'),
#         'news_num': ([r'^\d+$'], 'news_num-信息流每次加载中内容的条数'),
#         'newschn': ([r'^\d+$'], 'newschn-新闻频道，取值频道id'),
#         'nwt': (['1000', '1001', '1002', '1003', '1004', '1005'],
#                 'nwt-网络类型,取值=unknown-1000,wifi-1001,2G-1002,3G-1003,,4G-1004,5G-1005'),
#         'os': (['iOS', 'Android'], 'os-操作系统,取值iOS或者Android'),
#         'path': (['0', '1'], 'path-push进入标识,取值0或者1'),
#         'rc': ([r'^\d+$'], 'rc-加载次数，取值数字'),
#         'reposition': ([r'^\d+$'], 'reposition-流内广告相对位置'),
#         'rr': ([r'^\d+$'], 'rr-刷新次数，取值数字'),
#         'report_scene': ([r'^\d+$'], 'report_scene-上报时机，取值数字'),
#         'response_time': ([r'\d{13}'], 'response_time-请求到收到广告返回时间,单位ms'),
#         'sdkv': ([r'^(\d+)\.(\d+)\.(\d+)$', r'^(\d+)\.(\d+)\.(\d+)\.(\d+)$'], 'sdkv-广告sdk版本号'),
#         'span': ([r'^$', r'\S'], 'span-值由广告协议返回'),
#         'sv': ([r'iOS\s*\d+\.\d+\.\d+', r'Android\s*\d+\.\d+\.\d+'], 'sv-操作系统+版本号'),
#         'scene_type': (['live', 'ad', 'user', 'news', 'mat'], 'scene_type-上报场景，目前取值有live,user,ad,news,mat'),
#         'seq': ([r'^\d+$'], '事件序列'),
#         'timetag': ([r'\d{13}'], 'timetag-时间戳'),
#         'unapid': ([r'^\d+$'], 'uevent-uet上报事件类型'),
#         'unid': (['baidu'], 'uevent-uet上报事件类型'),
#         'uevent': ([r'^\d+$'], 'uevent-uet上报事件类型'),
#         'viewmonitor': ([r'^$', r'\S'], 'viewmonitor-值由广告协议返回'),
#         'vrpttype': ([r'^$', r'\S'], 'vrpttype-控制第三方上报，值由广告协议返回')
#     }
#
#     right_values = {}
#     wrong_values = {}
#
#     for key, value in passed_params.items():
#         if key in expected_values:
#
#             expected_value, expected_info = expected_values[key]
#             # 根据预期值的类型进行校验
#             if isinstance(expected_value, list) and any(re.match(pattern, value) for pattern in expected_value):
#                 # right_values[key] = f'{value} [校验通过，预期值是：{expected_info}]'
#                 right_values[key] = '{} [校验通过，预期值是：{}]'.format(value, expected_info)
#             else:
#                 # wrong_values[key] = f'{value} [不符合预期，预期值是：{expected_info}]'
#                 wrong_values[key] = '{} [不符合预期，预期值是：{}]'.format(value, expected_info)
#         else:
#             right_values[key] = '{} [校验通过,无预期值]'.format(value)
#
#     return right_values, wrong_values
#
#
# pass_ed = {'scene_type': '呃呃呃', 'asid': 'DB650EC0-A417-4B24-A931-30C21D9548AA_1698284550358', 'uevent': '7',
#            'timetag': '1698284550425', 'nwt': '1001', 'build_version': '7.0.60.224.1',
#            'launch_id': '7762D76D-E8F8-4545-B688-10C38F443149', 'appv': 'kkk', 'seq': '1', 'gbcode': '1156210300'}
#
# right_values, wrong_values = check_report_params_value(pass_ed)
#
# comparison_result = {
#             "取值异常参数": wrong_values,
#             "取值正常参数": right_values
#         }
#
# comparison_result_json = json.dumps(comparison_result,ensure_ascii=False)
# print(comparison_result_json)


# 原始集合
# abc = {'appv', 'test'}
#
# # 要移除的元素集合
# to_remove = {'page_event_id', 'refer', 'page_info', 'asid', 'delayreport'}
#
# # 移除存在于 to_remove 集合中的元素
# abc.difference_update(to_remove)
#
# print(abc)
# grades = {"Alice": 90, "Bob": 85, "Charles": 92,'b':''}
# # 获取键不存在时，返回默认值0
# stella_grade = grades.get("Stella")
# print(stella_grade)


def parse_viewmonitor(viewmonitor_value, url='http://10.18.70.119:4321/'):
    """
    解析viewmonitor并存在将key和value存在字典内
    :param viewmonitor_value:
    :param url:该url是引擎组提供的，目前固定是http://10.18.70.119:4321/，如遇到服务不好使就联系引擎的开发
    :return:返回解析成功的viewmonitor字典
    """
    if not viewmonitor_value:
        return {}  # 如果 viewmonitor_value 为空，则直接返回空字典
    # 构造POST请求的参数
    data = {
        'viewmonitor': viewmonitor_value,
    }

    # 发送POST请求
    response = requests.post(url, data=data)

    # 解析返回的HTML页面
    soup = BeautifulSoup(response.text, 'html.parser')

    # 获取解析结果
    result = soup.find('p').text

    viewmonitor_parsed = {}

    pairs = result.split('\t')  # 使用制表符分割解析结果中的参数和值
    for pair in pairs:
        split_result = pair.split('=')
        # 添加容错逻辑，在拆分之前检查拆分结果的数量。如果拆分结果大于等于2，则将第一个值作为键，将剩余的部分合并并作为值。这样可以确保即使拆分结果不符合预期，也能保证键和值的正确赋值。
        if len(split_result) >= 2:
            key = split_result[0]
            value = '='.join(split_result[1:])
            viewmonitor_parsed[key] = value
        else:
            # 处理无法拆分出键值对的情况
            viewmonitor_parsed[pair] = ''

    # 按key首字母排序
    # viewmonitor_parsed = dict(sorted(viewmonitor_parsed.items(), key=lambda x: x[0]))
    return viewmonitor_parsed


san = "fJ7QN3mXJhiGO4DxBZx7PQgc1buR5sfQ%2FHshknhdYaZsSyKYPnhF0Cg2qrzOZ%2Ftayw7E0JR8U2GwaBvwxA58m61dXBTs6AXXK4U%2FZgMrF4xYw7ksD0e0LeJsm9xGbjfk%2BlczzW2T8d8myDgJi4013dseTbeUkfDiqZ13hCr2S9HFmb%2FjeAhV5Cfh6u%2FMMnAu%2FylGlcij6dIz60dcq3Ay29J7c4z5ni0OWB%2FqIW6ZYmEfEgURfMNeO2O2A7g2V5%2FiBEfpyADB3f5z5ontCWzyEIMKNi2ceA9ufKKsADe9X0g%3D%09tt2%3D1699242840074%09delay%5Freport%5Fttl%3D30"
aa = parse_viewmonitor(san)
print(aa)